/*
@(#)OssController   2024-11-08
 
Copyright (c) 2011-2024 杭州湖畔网络技术有限公司 
保留所有权利 
本软件为杭州湖畔网络技术有限公司所有及包含机密信息，须遵守其相关许可证条款进行使用。
Copyright (c) 2011-2024 HUPUN Network Technology CO.,LTD.
All rights reserved.
This software is the confidential and proprietary information of HUPUN
Network Technology CO.,LTD("Confidential Information").  You shall not
disclose such Confidential Information and shall use it only in
accordance with the terms of the license agreement you entered into with HUPUN.
Website：http://www.hupun.com
*/
package org.obp.oss.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.RandomUtils;
import org.obp.core.result.ApiResult;
import org.obp.oss.config.OssConfig;
import org.obp.oss.domain.OssPolicy;
import org.obp.oss.enums.OssUploadPathEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @author: Jackey 2024/11/8
 */
@Slf4j
@RestController
@RequestMapping("/v1/work/oss")
@Api(tags = "OSS密钥接口")
public class OssController {

    @Autowired
    private OssConfig ossConfig;

    @ApiOperation("获取OSS上传秘钥")
    @GetMapping("/policy")
    public ApiResult<OssPolicy> getPolicy(@ApiParam(value = "文件类型：图片-pic/文件-file/文档-doc/视频-video/音频-voice")
                                          @RequestParam String fileType, @RequestParam String fileName) {
        OssPolicy ossPolicy = generatePostPolicy(fileType, fileName, false);
        return ApiResult.ok(ossPolicy);
    }

    /**
     * 生成签名给前端直传
     *
     * @return 上传oss路径名
     */
    private OssPolicy generatePostPolicy(String fileType, String fileName, boolean isOriginalName) {
        OssPolicy ossPolicy = new OssPolicy();
        String bucket = ossConfig.getBuckName();
        String host = "https://" + bucket + "." + ossConfig.getEndPoint();
        String dir;

        dir = generateDir(fileType);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        Date now = new Date();
        String timestamp = String.valueOf(System.currentTimeMillis());
        StringBuilder ossFilePath = new StringBuilder();
        ossFilePath.append(dir);
        ossFilePath.append(sdf.format(now));
        if (isOriginalName) {
            ossFilePath.append("/n_");
            ossFilePath.append(timestamp);
            ossFilePath.append("_");
            ossFilePath.append(RandomUtils.nextInt(1000, 9999));
            ossFilePath.append("/");
            ossFilePath.append(fileName);
        } else {
            String fileExtension = FilenameUtils.getExtension(fileName);
            ossFilePath.append(UUID.randomUUID().toString().replaceAll("-", ""));
            ossFilePath.append(FilenameUtils.EXTENSION_SEPARATOR);
            ossFilePath.append(fileExtension);
        }

        OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndPoint(),
                ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
        try {
            long expireEndTime = System.currentTimeMillis() + ossConfig.getExpireSecond() * 1000;

            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConditions = new PolicyConditions();
            policyConditions.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 200 * 1024 * 1024);
            policyConditions.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConditions);
            byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            ossPolicy.setAccessId(ossConfig.getAccessKeyId());
            ossPolicy.setSignature(postSignature);
            ossPolicy.setExpire(String.valueOf(expireEndTime / 1000));
            ossPolicy.setHost(host);
            ossPolicy.setCdnHost(ossConfig.getCdnHost());
            ossPolicy.setDir(dir);
            ossPolicy.setPolicy(encodedPolicy);
            ossPolicy.setFileName(ossFilePath.toString());
            return ossPolicy;

        } catch (Exception e) {
            log.error(e.getMessage(), e);

        } finally {
            ossClient.shutdown();
        }

        return null;
    }

    private String generateDir(String fileType) {
        String dir;
        switch (fileType) {
            case "pic":
                dir = OssUploadPathEnum.OSS_UPLOAD_PIC_PATH.getPath();
                break;
            case "voice":
                dir = OssUploadPathEnum.OSS_UPLOAD_VOICE_PATH.getPath();
                break;
            case "video":
                dir = OssUploadPathEnum.OSS_UPLOAD_VIDEO_PATH.getPath();
                break;
            case "doc":
                dir = OssUploadPathEnum.OSS_UPLOAD_DOC_PATH.getPath();
                break;
            case "cert":
                dir = OssUploadPathEnum.OSS_UPLOAD_PATH_CERTIFICATE.getPath();
                break;
            case "apk":
                dir = OssUploadPathEnum.OSS_UPLOAD_APK_PATH.getPath();
                break;
            default:
                dir = OssUploadPathEnum.OSS_UPLOAD_PATH_DEFAULT.getPath();
        }
        return dir;
    }

}